/*************************************************************************
	> File Name: conn.cpp
	> Author: Wu Junqiang
	> Mail: 15769154659@163.com 
	> Created Time: 2018年02月04日 星期日 03时04分23秒
	> Note: 
 ************************************************************************/

#include "conn.h"

static void* Data_handle(void* sock_fd);
string json_to_protocol(string data);
bool json_to_login(string data);
string client_query_user(string data);
bool Inser_SportData(string data);
string Query_SpotData(string data);

int main()
{
    
    int sockfd_server;
    int sockfd;
    int fd_temp;
    struct sockaddr_in s_addr_in;
    struct sockaddr_in s_addr_client;
    int client_length;

    sockfd_server = socket(AF_INET,SOCK_STREAM,0);
    assert(sockfd_server != -1);

    memset(&s_addr_in, 0, sizeof(s_addr_in));
    s_addr_in.sin_family = AF_INET;
    s_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
    s_addr_in.sin_port = htons(SOCKET_PORT);
    fd_temp = bind(sockfd_server,(struct sockaddr*)(&s_addr_in),sizeof(s_addr_in));
    if(fd_temp == -1)
    {
        cout << stderr << "bind error!" << endl;
        exit(1);
    }
    fd_temp = listen(sockfd_server,MAX_CONN_LIMIT);
    if(-1 == fd_temp)
    {
        cout << stderr << "listen error!" << endl;
        exit(1);
    }
    while(true)
    {
        cout <<"Waiting for new connection...." << endl;
        pthread_t thread_id;
        client_length = sizeof(s_addr_client);

        sockfd = accept(sockfd_server,(struct sockaddr*)(&s_addr_client),(socklen_t *)(&client_length));
        if(sockfd == -1)
        {
            cout << stderr << "Accept error!" << endl;
            continue;
        }
        if(pthread_create(&thread_id,NULL,Data_handle,(void*)(&sockfd))==-1)
        {
            cout << stderr << "pthread_create error!" << endl;
            break;
        }
    }
    int ret = shutdown(sockfd_server, SHUT_WR);
    assert(ret != -1);

    cout << "Server shutdown" << endl;
    return 0;
}

static void* Data_handle(void* sock_fd)
{
    int fd = *(int*)sock_fd;
    int i_recvBytes;
    char data_recv[BUFFER_LENGTH];
    string protocol;
    bool isLogin = false;
    
    while(true)
    {
        cout << "Waiting for reques......" << endl;
        memset(data_recv,'\0', BUFFER_LENGTH);
       
        i_recvBytes = recv(fd, data_recv,sizeof(data_recv),0);
        cout << "data_recv :" << data_recv << endl;
        protocol =  json_to_protocol(data_recv);

        if(i_recvBytes == 0)
       {
            cout << "Maybe the client has closed!" << endl;
       //     exit(0);
            break;
       }
        if(i_recvBytes == -1)
        {
            cout << stderr << " read error" << endl;
            break;
        }
        //客户端退出
        if(strcmp(data_recv,"quit") == 0)
        {
            cout << "quit command!"  << endl;
            break;
        }
        cout << protocol.c_str() << endl;
        //测试字符
        if(protocol.compare("json") == 0)
        {
           // send(fd,temp,sizeof(Msg),0);
        }
        //登录
        if(protocol.compare("login") == 0)
        {
            isLogin = json_to_login(data_recv);
            cout << "isLogin : " << isLogin << endl;    
            if(isLogin)
            {
                int len = strlen("login successful");
                char l[4];
                sprintf(l,"%d",len);
                send(fd, l, 4, 0);
                send(fd, "login successful",strlen("login successful"), 0);
            }
            else
            {
                int len = strlen("login failed");
                char l[4];
                sprintf(l,"%d",len);
                send(fd, l, 4, 0);
                send(fd, "login failed", strlen("login failed"), 0);
            }
        }
        if(protocol.compare("queryuserbyname") == 0)
        {

            //如果登录
//            if(isLogin == true)
//            {

            string  str = client_query_user(data_recv);
         //   const char* s = str.c_str();
            int len = strlen(str.c_str());
            char l[4];
            sprintf(l,"%d",len);
            send(fd,l,4,0);
            send(fd,str.c_str(),strlen(str.c_str()), 0);
     //       cout << "str:" << str << endl;
//            }
            //没有登录
//            else
//            {
 //               const char* s = "user not login";
 //               int len  = sizeof(s);
  //              char l[4];
  //              sprintf(l,"%d", len);
  //              send(fd,l, 4, 0);
  //              send(fd, s, sizeof(s), 0);
//            }
        }
        //插入用户运动数据
        if(protocol.compare("insertsportdata") == 0 )
        {
            bool issuccess = Inser_SportData(data_recv);

            if(issuccess)
            {
                  string str = "successful";
                  char l[4];
                  int len = strlen(str.c_str());
                  sprintf(l,"%d", len);
                  send(fd,l,4,0);
                send(fd,"successful",strlen("successful"),0);
            }
            else
            {
                  string str = "failure";
                  char l[4];
                  int len = strlen(str.c_str());
                  sprintf(l,"%d", len);
                  send(fd,l,4,0);
               
                send(fd,"failure",strlen("failure"),0);
            }
        }
        //查询用户运动数据
        if(protocol.compare("querysportdatabyname") == 0)
        {
            string str = Query_SpotData(data_recv);
            int len = strlen(str.c_str());
            char l[10];
            sprintf(l,"%d",len);
            send(fd,l,10,0);
            send(fd,str.c_str(),(size_t)str.length(),0);

        }
    }
    cout << "terminating current client_connection..." << endl;
    close(fd);
    pthread_exit(NULL);
}

//测试通过
string json_to_protocol(string data)
{
    string protocol;
    Json::Reader reader;
    Json::Value root;
    if(reader.parse(data,root))
    {
        protocol = root["protocol"].asString();
    }
    return protocol;
}
//"{\"protocol\":\"login\",\"name\":\"jiao\",\"password\":\"123\"}"
//登录json格式 用户登录 测试通过
bool json_to_login(string data)
{
    User user;
    string name;
    string password;
    Json::Reader reader;
    Json::Value root;
    //获取登录姓名．
    if(reader.parse(data,root))
    {
        name = root["name"].asString();
        password = root["password"].asString();
    }
 //   cout << "name: "<< name  << "password：" << password << endl;

    if(user.QueryUser(name))
    {
    //    cout << "hello world" << endl;
        if(user.UserLogin(name, password))
        {
       //     cout << "登录成功" << endl;
            return true;
        }
    }
    return false;
}

//数据格式 "{\"pro6tocol\":\"queryuserbyname\",\"name\":\"jiao\"}"
//查询用户信息
//返回数据格式：{\"userdata\":[{\"name\":\"jiao\",\"password\":\"\",\"sex\":\"女\",\"age\":\"12\",\"height\":\"175\",\"weight\":\"60\",\"contactInfo\":\"123456789\"}]}
//未测试
string client_query_user(string data)
{
    Person person;
    User user;
    string name;
    Json::Reader reader;
    Json::Value rootr;
    Json::FastWriter fswrite;
    Json::Value rootw;
    Json::Value temp;
    
    if(reader.parse(data,rootr))
    {
        name = rootr["name"].asString();
    }
    rootw["name"] = name;
    person =  user.QueryUserInfo(name);

   // temp["name"] = person.name;
    temp["sex"] = person.sex;
    temp["age"] = person.age;
    temp["height"] = person.height;
    temp["weight"] = person.weight;
    temp["cantactInfo"] = person.contactInfo;

    rootw["userdata"] = temp;
    string str = fswrite.write(rootw);
    
    return str; 
}


//数据请求格式："{"protocol":"insertsportdata","data":{"name":"jiao","sportclass":"","mac":"","sporttime":"","group":"","groupnum":"","isstandard":"","info":""}}"
//插入用户运动数据
//数据格式
//返回数据格式：true/false
//测试状态：未测试
bool Inser_SportData(string data)
{
    SportData sportdata;
    User user;

    Json::Reader reader;
    Json::Value root;

    if(!reader.parse(data,root))
    {
        return false;
    }

    Json::Value temp = root["data"];
    
    sportdata.name =  temp["name"].asString();
    sportdata.sportClass = temp["sportclass"].asString();
    sportdata.mac = temp["mac"].asString();
    sportdata.sportTime = temp["sporttime"].asString();
    sportdata.group = temp["group"].asString();
    sportdata.groupNum = temp["groupnum"].asString();
    sportdata.isStandard = temp["isstandard"].asString();
    sportdata.info = temp["info"].asString();


    return user.InsertUserSportdata(sportdata);
}

//数据请求格式：{"protocol":"querysportdatabyname","name":"jiao"}
//查询用户运动数据(name)
//返回数据格式：{"name":"jiao","data":[{"group":"","groupTime":"","sporttime":"","isStandard":"","info":""},{}]}
//测试状态：未测试
string Query_SpotData(string data)
{


    string str;
    list<SportData> sport;
    User user;
    string name;
    int i = 0;

    Json::Reader reader;
    Json::Value rootr;

    Json::FastWriter fw;
    Json::Value rootw;
    Json::Value temp;
    if(reader.parse(data,rootr))
    {
        name = rootr["name"].asString();
    }
    rootw["name"] = name;

    sport =  user.GetUserSportdata(name);

    //使用迭代器遍历链表
    for(list<SportData>::const_iterator iter = sport.begin(); iter != sport.end();iter++, i++)
    {
        temp[i]["group"] = (*iter).group;
        temp[i]["grounum"] =  (*iter).groupNum;
        temp[i]["sporttime"] = (*iter).sportTime;
        temp[i]["isStandard"] = (*iter).isStandard;
        temp[i]["info"] = (*iter).info;

        rootw["data"].append(temp[i]);
   //     cout << "I:" << i << endl;
    }

        str = fw.write(rootw);
    return str;
}
